import _ from "lodash"
import { removeHtmlTag } from '../../utils/index'

// 触发规则 什么时候触发问卷校验
const ruleTrigger = {
  INPUT: 'blur',
  TEXTAREA: 'blur',
  INPUT_MAP: 'input',
  SELECT: 'change',
  RADIO: 'input',
  CHECKBOX: 'input',
  CASCADER: 'change',
  PROVINCE_CITY: 'change',
  DATE: 'change',
  MATRIX_SELECT: 'change',
  MATRIX_SCALE: 'change',
  MATRIX_INPUT: 'change',
  MATRIX_TABLE: ['input','change'],
}

// 验证身份证格式
/**
 * 验证身份证号码
 * @param { String } code 身份证号码
 */
function identityIDCard(code) {
  // 身份证号前两位代表区域
  const city = {
    11: '北京',
    12: '天津',
    13: '河北',
    14: '山西',
    15: '内蒙古',
    21: '辽宁',
    22: '吉林',
    23: '黑龙江 ',
    31: '上海',
    32: '江苏',
    33: '浙江',
    34: '安徽',
    35: '福建',
    36: '江西',
    37: '山东',
    41: '河南',
    42: '湖北 ',
    43: '湖南',
    44: '广东',
    45: '广西',
    46: '海南',
    50: '重庆',
    51: '四川',
    52: '贵州',
    53: '云南',
    54: '西藏 ',
    61: '陕西',
    62: '甘肃',
    63: '青海',
    64: '宁夏',
    65: '新疆',
    71: '台湾',
    81: '香港',
    82: '澳门',
    91: '国外 '
  }
  const idCardReg = /^[1-9]\d{5}(19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i // 身份证格式正则表达式
  let errorMessage = '' // 错误提示信息
  let isPass = true // 身份证验证是否通过（true通过、false未通过）

  // 如果身份证不满足格式正则表达式
  if (!code) {
    isPass = false
  } else if (!code.match(idCardReg)) {
    isPass = false
  } else if (!city[code.substr(0, 2)]) {
    // 区域数组中不包含需验证的身份证前两位
    isPass = false
  } else if (code.length === 18) {
    // 18位身份证需要验证最后一位校验位
    code = code.split('')
    // ∑(ai×Wi)(mod 11)
    // 加权因子
    const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    // 校验位
    const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
    let sum = 0
    let ai = 0
    let wi = 0
    for (let i = 0; i < 17; i++) {
      ai = parseInt(code[i])
      wi = factor[i]
      sum += ai * wi // 开始计算并相加
    }
    const last = parity[sum % 11] // 求余
    if (last.toString() !== code[17]) {
      isPass = false
    }
  }
  return isPass

}


// 处理RADIO CHECKBOX 其他输入必填校验
const validateOtherInput = (rule, value, callback, formModel, cur) => {
  // 是否设置了必填
  if (false === cur.config.otherRequired) {
    callback()
  }
  // 0 等于选中其他
  if (value === 0 || (Array.isArray(value) && value.includes(0))) {
    if (!formModel[`${rule.field}other`]) {
      callback(new Error('请输入其他内容'))
    } else {
      callback()
    }
  } else {
    callback()
  }
}
const validateMatrixTable = (rule, value, callback,item) => {
  console.log(item,'item')
  // 0 等于选中其他
  let isValidate = true
  if (value) {
    // 如果是对象
    if (!_.isArray(value) && _.isObject(value)) {
      if(_.keys(value).length){
        _.keys(value).forEach(key1 => {
          // 是不是对象
          let value1 = value[key1]
          // 矩阵填空
            if (!_.isArray(value1) && _.isObject(value1)) {
              _.keys(value1).forEach(key2 => {
                    let value2 = value1[key2]
                    item.table.columns.forEach(v=>{
                      if(v.id == key2){
                        if(v.columnForm.type==1){//单选多选
                          if(value2){
                            const changeVal = value2[value2.length - 1]
                            // 是否是互斥,不是返回-1，是的话返回对应的索引
                            const isExclusive = v.columnForm.multipleOption.findIndex(
                              (e) => e.value === changeVal.value
                            )
                            if(isExclusive == -1){
                              if(v.columnForm.min){//为0不限制
                                  if(value2.length < v.columnForm.min){
                                    isValidate = false
                                    return
                                  }
                              }
                            }
                            if(v.columnForm.max){//为0不限制
                              if(value2.length > v.columnForm.max){
                                  isValidate = false
                                  return
                              }
                            }
                          }

                          if(v.columnForm.required){
                            if(value2 == null){
                              isValidate = false
                              return
                            }else if(_.isObject(value2) && !_.isArray(value2)){
                                if(!value2.value){
                                  isValidate = false
                                  return
                                }
                            }else if(_.isArray(value2)){
                                if( value2.length == 0){
                                  isValidate = false
                                  return
                                }
                            }
                          }
                        }else if(v.columnForm.type==2 || v.columnForm.type==3){//填空问答
                            if(v.columnForm.required){
                              if (value2 == null) {
                                isValidate = false
                                return
                              }else{
                                let validator = ''
                                switch (v.columnForm.testType) {
                                  case 1:
                                    validator = ''
                                    break
                                  case 2:
                                  // 阿拉伯数字
                                    validator = '^[0-9]+$'
                                    break
                                  case 3:
                                  // 固定电话
                                    validator = '^[0-9]{3,4}-[0-9]{7,8}$'
                                    break
                                  case 4:
                                  // 手机号
                                    validator = '^1[3-9][0-9]{9}$'
                                    break
                                  case 5:
                                  // 邮政编码
                                    validator = '^[1-9][0-9]{5}$'
                                    break
                                  case 6:
                                  // Email
                                    validator = '^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$'
                                    break
                                  case 7:
                                  // URL
                                  validator = "[a-zA-z]+://[^\s]*";
                                    break
                                  case 8:
                                  // 身份证
                                    validator = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
                                    break
                                  case 9:
                                    // 日期
                                    // 2022-07-08
                                    validator = '^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))+$'
                                    break
                                  case 10:
                                  // 中文
                                    validator = '^[\u4e00-\u9fa5]+$'
                                    break
                                  case 11:
                                  // 中英文
                                    validator = '^[\u4e00-\u9fa5a-zA-Z]+$'
                                    break
                                }
                                if(!new RegExp(validator).test(value2)){
                                  isValidate = false
                                  return
                                }
                              }
                            }else{
                              if (value2) {
                                let validator = ''
                                switch (v.columnForm.testType) {
                                  case 1:
                                    validator = ''
                                    break
                                  case 2:
                                  // 阿拉伯数字
                                    validator = '^[0-9]+$'
                                    break
                                  case 3:
                                  // 固定电话
                                    validator = '^[0-9]{3,4}-[0-9]{7,8}$'
                                    break
                                  case 4:
                                  // 手机号
                                    validator = '^1[3-9][0-9]{9}$'
                                    break
                                  case 5:
                                  // 邮政编码
                                    validator = '^[1-9][0-9]{5}$'
                                    break
                                  case 6:
                                  // Email
                                    validator = '^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$'
                                    break
                                  case 7:
                                  // URL
                                  validator = "[a-zA-z]+://[^\s]*";
                                    break
                                  case 8:
                                  // 身份证
                                    validator = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
                                    break
                                  case 9:
                                    // 日期
                                    // 2022-07-08
                                    validator = '^([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8])))+$'
                                    break
                                  case 10:
                                  // 中文
                                    validator = '^[\u4e00-\u9fa5]+$'
                                    break
                                  case 11:
                                  // 中英文
                                    validator = '^[\u4e00-\u9fa5a-zA-Z]+$'
                                    break
                                }
                                if(!new RegExp(validator).test(value2)){
                                  isValidate = false
                                  return
                                }
                              }
                            }

                        }else if(v.columnForm.type==4 && v.columnForm.required){//上传
                          if(value2 == null){
                            isValidate = false
                            return
                          }else if(_.isArray(value2)){
                            if( value2.length == 0){
                              isValidate = false
                              return
                            }
                          }
                        }
                      }
                    })
              })
            }
        })
      }else{
        var total =0
        item.table.columns.forEach(v=>{
          if(v.columnForm.required){
            total++
          }
        })
        if(total !=0){
          isValidate=false
        }
      }
    }
    var label=[]
    item.table.columns.forEach(v=>{
      if(v.columnForm.required){
        label.push(v.label)
      }
    })
    if (!isValidate) {
      callback(new Error(label.join(',')+'为必填列，请输入格式正确的值'))
    } else {
      callback()
      // var node = document.getElementsByClassName('el-form-item__error')
      // if(!node.length){
      //   callback()
      // }else{
      //   callback(new Error(label.join(',')+'为必填列，请输入格式正确的值'))
      // }
    }
    //
    // }
    // if (!isValidate) {
    //   callback(new Error('请输入全部矩阵组件的值,并且保持值格式正确'))
    // } else {
    //   var node = document.getElementsByClassName('el-form-item__error')
    //   if(!node.length){
    //     callback()
    //   }else{
    //     callback(new Error('请输入全部矩阵组件的值,并且保持值格式正确'))
    //   }
    // }


  }
}

// 校验矩阵输入
const validateMatrixInput = (rule, value, callback) => {
  // 0 等于选中其他
  let isValidate = true
  if (value) {
    // 如果是对象
    if (!_.isArray(value) && _.isObject(value)) {
      if(_.keys(value).length){
        _.keys(value).forEach(key1 => {
          // 是不是对象
          let value1 = value[key1]
          // 矩阵填空
          if (!_.isArray(value1) && _.isObject(value1)) {
            _.keys(value1).forEach(key2 => {
              let value2 = value1[key2]
              if (!value2) {
                isValidate = false
                return
              }
            })
          }
        })
      }else{
        isValidate = false
      }

    }
    if (!isValidate) {
      callback(new Error('请输入全部矩阵组件的值'))
    } else {
      callback()
    }
  }
}
const validateMatrixSelect = (rule, value, callback, item) => {
  if (item.table.rows.length !== _.keys(value).length) {
    callback(new Error('请选择全部矩阵组件的值'))
  } else {
    callback()
  }
}

const validateMatrixScale = (rule, value, callback, item) => {
  if (item.table.rows.length > _.keys(value).length) {
    callback(new Error('请选择全部矩阵组件的值'))
  } else {
    item.table.rows.forEach(row => {
      if (!value[row.id]) {
        callback(new Error('请选择全部矩阵组件的值'))
        return
      }
    })
    callback()
  }
}


export default {
  data() {
    return {}
  },
  methods: {
    handleUploadValidate(cur, config) {
      const {typeId, vModel } = cur
      const formItemArray = this.$refs[vModel]

      const formItemInstance = formItemArray.find(el => el.$refs[vModel])

      if (formItemInstance) {
        const validator = (rule, value, callback) => {
          const uploadInstance = formItemInstance.$refs[vModel]
          const uploadStatus = uploadInstance.getUploadStatus()
          if (uploadStatus === 2) {
            callback(new Error('有文件正在上传中，请上传完成后提交'))
          } else {
            callback()
          }
        }
        if (config.regList.find(item => item.validator && item.validator === validator)) {
          // TODO
        } else {
          config.regList.push({
            trigger: 'change',
            validator
          })
        }

      }

    },
    buildRule(cur, rules) {
      const config = cur.config
      // 其它输入框校验
      try {
        this.handleOtherInput(cur, config)
      } catch (e) {
      }
      // 输入框校验
      this.handleInputValidate(cur, config)
      if (Array.isArray(config.regList)) {
        if (config.required) {
          // 矩阵系列组件 必填特殊处理 需要校验每项都有值
          this.handleSpecialRequired(cur, config)
          const required = {
            required: config.required, message: cur.placeholder
          }
          const label = removeHtmlTag(config.label)
          if (Array.isArray(config.defaultValue)) {
            required.type = 'array'
            required.message = `请至少选择一个${label}`
          }
          (required.message === undefined || !required.message)  && (required.message = `${label}不能为空`)
          config.regList.push(required)

        }else{
          if(cur.typeId == "MATRIX_TABLE"){//多维表格特殊处理
            let validator = null
            validator = (rule, value, callback) => validateMatrixTable(rule, value, callback, cur)
            config.regList.push({ validator })
          }
        }
        if (['TEXTAREA','INPUT'].includes(cur.typeId)) {
          if(cur.minlength){
            config.regList.push({
              validator: (rule, value, callback) => {
                if(value){
                  if (value.length < cur.minlength) {
                    callback(new Error('至少输入'+cur.minlength+'个字符'))
                  }else{
                    callback()
                  }
                }
              }
            })
          }
        }

        rules[cur.vModel] = config.regList.map(item => {
          item.pattern && (item.pattern = eval(item.pattern))
          item.trigger = ruleTrigger && ruleTrigger[cur.typeId]
          return item
        })
      }

      // if (['UPLOAD'].includes(cur.typeId)) {
      //   this.handleUploadValidate(cur, config)
      // }
      if (config.children) this.buildRules(config.children, rules)
    }, // 处理特殊组件非空校验
    handleSpecialRequired(cur, config) {
      // 矩阵系列组件 必填特殊处理 需要校验每项都有值
      let validator = null
      switch (cur.typeId) {
        case 'MATRIX_TABLE':
          validator = (rule, value, callback) => validateMatrixTable(rule, value, callback, cur)
          break
        case 'MATRIX_INPUT':
          validator = validateMatrixInput
          break
        case 'MATRIX_SELECT':
          validator = validateMatrixInput
          break
        case 'MATRIX_SCALE':
          validator = (rule, value, callback) => validateMatrixScale(rule, value, callback, cur)
          break
        case 'RATE':
          validator = (rule, value, callback) => {
            if (!value || value === 0) {
              callback(new Error(cur.placeholder))
            } else {
              callback()
            }
          }
          break
        case 'CHECKBOX':
          validator = (rule, value, callback) => {
            if (cur.min && value.length < cur.min) {
              return callback(new Error(`最少选择${cur.min}项`))
            }
            if (cur.max && value.length > cur.max) {
              return callback(new Error(`最多选择${cur.max}项`))
            }
            callback()
          }
          break
        case 'RESERVE_TIME_RANGE':
        case 'RESERVE_DAY':
          validator = (rule, value, callback) => {
            console.log(value)
            if (!value || !Object.keys(value)) {
              return callback(new Error(`请选择`))
            }
            callback()
          }
          break
        case 'PROVINCE_CITY':
            validator = (rule, value, callback) => {
              this.$nextTick(() => {
                value = this.formModel[cur.vModel]
                if(value){
                  if(config.requireDetailAddr){
                    if (!value.detailAddr || (Array.isArray(value.cascadeValue) && value.cascadeValue.length < 2)) {
                      return callback(new Error(`${cur.placeholder}`))
                    }
                    else{
                      // if (Array.isArray(value.cascadeValue) && value.cascadeValue.length < 2) {
                      //   return callback(new Error(`${cur.placeholder}`))
                      // }else{
                      //
                      // }
                      callback()
                    }
                  }else{
                    if (Array.isArray(value.cascadeValue) && value.cascadeValue.length < 2) {
                      return callback(new Error(`${cur.placeholder}`))
                    }else{
                      callback()
                    }
                  }
                }else{
                  return callback(new Error(`${cur.placeholder}`))
                }
              })
          }

          break
        default:
      }
      if (validator) {
        config.regList.push({ validator })
      }
    }, // 多选 单选 其他输入框特殊处理校验规则
    handleOtherInput(cur, config) {
      // 必填其他输入框校验
      if (['RADIO', 'CHECKBOX'].includes(cur.typeId)) {
        // 是否存在其他
        let flag = cur.config.options?.findIndex(o => o.value === 0) > -1 && config.required
        const required = {
          validator: (rule, value, callback) => {
            validateOtherInput(rule, value, callback, this.formModel, cur)
          }, message: cur.placeholder
        }
        if (flag) {
          config.regList.push(required)
        }
      }
    }, // 输入框常用校验处理
    handleInputValidate(cur, config) {
      // INPUT数据类型校验
      if (['INPUT'].includes(cur.typeId) && cur.config.dataType) {
        const rule = cur.config.dataType

        if (rule.type === 'phone') {
          config.regList.push({
            type: null, pattern: /^1[3456789]\d{9}$/, message: rule.message
          })
        } else if (rule.type === 'identity') {
          config.regList.push({
            validator: (rule, value, callback) => {
              if (value && !identityIDCard(value)) {
                callback(new Error('请输入正确身份证'))
              }
              callback()
            }, message: rule.message
          })
        } else if (rule.type === 'zh') {
          config.regList.push({
            type: null,
            pattern: /^[\u4e00-\u9fa5\d\p{P}]+$/u,
            message: rule.message
          })
        }else if (rule.type === 'zh2') {
          config.regList.push({
            type: null,
            pattern: /^[\u4e00-\u9fa5]+$/,
            message: rule.message
          })
        }else {
          config.regList.push(rule)
        }

      }
    },

  }
}
